﻿<html>
<head>
    <title>印章拖动示例</title>
    <!-- <link href="./css/jquery.zsign.css" rel="stylesheet" type="text/css" /> -->
    <!-- <script src="./js/jquery-1.7.1.min.js" type="text/javascript"></script> -->
    <script src="../js/jquery-3.3.1.min.js" type="text/javascript"></script>
    <script src="../js/polyfill.min.js" type="text/javascript"></script>
    <script src="../js/es6-promise.auto.min.js"></script>
    <script src="../js/pdfjs-dist/build/pdf.min.js"></script>
    <link href="../css/bootstrap.min.css" rel="stylesheet" type="text/css">
    <link href="../css/sign.css" rel="stylesheet" type="text/css">
    <link href="../css/style.css" rel="stylesheet"/>
    <script src="../js/ui.js"></script>
</head>

<body>
<!-- <div>
<p>温馨提示</p>
<h1>PDF.js 'Hello, world!' example <a href="http://mozilla.github.io/pdf.js/examples/">参考</a></h1>
<h2>Internet Explorer 8 及更早 IE 版本或 Safari 5.1 及更早版本的浏览器不支持 drag 事件。<a href="http://www.runoob.com/try/try.php?filename=tryjsref_ondrag_all">参考</a></h2>
<h3>draggabilly 插件 pdf内印章拖动</h3>
</div> -->


<div class="ui-h100">
    <div class="sign_warp">
        <div class="sign_left">
            <ul class="docsList" id="docsList">
                <!-- <li class="current" onclick="changeDocs(event, 0)">文档A</li> -->
            </ul>
        </div>
        <div class="sign_content" id="signContainer">

        </div>
        <div class="sign_right">
            <div class="signList" id="signList"></div>

            <div class="seal-btn-wrapper">
                <button class="btn btn-danger btn-lg btn-block" onclick="submitSign()" type="button">确认签署</button>
            </div>
        </div>
    </div>
</div>
<script>
    var pdfjsLib = window['pdfjs-dist/build/pdf'];
    pdfjsLib.PDFJS.workerSrc = '/mk_api/signature/js/pdfjs-dist/build/pdf.worker.js';
    pdfjsLib.PDFJS.cMapUrl = '/mk_api/js/pdfjs-dist/cmaps/';
    pdfjsLib.PDFJS.cMapPacked = true;
    var fdAttId = null;
    var fdProjectId = null;
    var fdFilename = null;
    var fdUrlHeard = null;
    var fdLoginName = null;
    var fdEntityKey = null;
    // 提交印章数组
    const posBean = [];
    // 默认文档
    let docsCurrentNumber = 0
    // 印章
    const sealList = [{
        sealImg: '/mk_api/signature/seal/seal.png',
        sealId: '签署人标识'
    }]

    // 文档列表
    const docsList = [
        {
            loadType: 'byBase64',
            title: '待签章的PDF文件',
            docValue: 'HT201808260001'

        }
        // {
        //     loadType: 'byFilePath',
        //     title: '相对路径',
        //     docValue: './pdf/test_Black.pdf'
        // }
    ]

    // 初始化
    const init = function () {
        // 印章列表
        // sealList.forEach(item => {
        sealList.forEach(function (item) {
            const template =
                '<div class="sealItems" sealId= "' + item.sealId + '" draggable="true" ondragstart= \'_ondragstart(event, {sealImg: "' + item.sealImg + '", sealId: "' + item.sealId + '"})\' ondragend= \'_ondragend(event)\'></div>'
            $('#signList').append(template)
        });

        // 文档列表
        docsList.forEach(function (item, index) {
            // const template = '<li onclick="changeDocs(event, ${index})">item.title</li>'
            const template = "<li onclick='changeDocs(event," + index + ")'>" + item.title + "</li>"
            $('#docsList').append(template)
            // 初始化 posBean
            posBean[index] = [];
        })
    }

    // 渲染印章
    const rendererSeal = function (pageNumber, pageViewOffsetHeight) {
        posBean[docsCurrentNumber].length && posBean[docsCurrentNumber].forEach(function item() {
            if (item.posPage == pageNumber) {
                rendererSealTemplate(item, pageViewOffsetHeight)
            }
        })
    }

    // 渲染 pages
    const renderer = function (pdf, pageNumber) {
        pdf && pdf.getPage(pageNumber).then(function (page) {
            console.log('Page loaded');
            console.log(page, 'page')

            // pdf 解析的比例， 获取原始文档尺寸 scale = 1; 如果文档放大，印章x y 需要同比例缩放
            var scale = 1;
            var viewport = page.getViewport(scale);

            // Prepare canvas using PDF page dimensions
            // 遍历 pdf.numPages， 传递 不同的 Canvas ID
            var canvas = document.getElementById('pageCanvas_' + pageNumber);
            console.log(canvas, '')
            var context = canvas.getContext('2d');

            // 设置 canvas
            canvas.height = viewport.height;
            canvas.width = viewport.width;

            // 设置外层大小
            var pageView = document.getElementById('pageView_' + pageNumber)
            pageView.style.height = viewport.height + 'px'
            pageView.style.width = viewport.width + 'px'

            // Render PDF page into canvas context
            page.render({
                canvasContext: context,
                viewport: viewport
            }).then(function () {
                // 渲染印章
                console.log('Page rendered');

                rendererSeal(pageNumber, pageView.offsetHeight)
                console.log('PageSeal rendered');
            }, function err() {
                console.log('Page error');
            });
        });
    }

    // 新增dom
    const rendererTemplate = function (pageNumber) {
        const template =
            "<div id='pageView_" + pageNumber + "' class='pageView' ondragenter = '_ondragenter(event)' ondragover = '_ondragover(event)' ondragleave = '_ondragleave(event)' ondrop = '_ondrop(event," + pageNumber + ")'><canvas id='pageCanvas_" + pageNumber + "' class='pageCanvas'></canvas></div>"
        $('#signContainer').append(template)
    }

    // 新增印章dom
    const rendererSealTemplate = function (dragData, pageViewOffsetHeight) {
        const template = "<div id='drag" + dragData.id + "' class='sealView' style='width:" + dragData.width + "px; height:" + dragData.height + "px; left: " + (dragData.posX - (dragData.width / 2)) + "px; top: " + (pageViewOffsetHeight - (dragData.height / 2) - dragData.posY) + "px; background-image: url(" + dragData.sealImg + ");'><button class='sealDel' onclick='delSealItem(\"" + dragData.id + "\")'>删除</button></div>"
        $("#pageView_" + dragData.posPage).append(template)
    }

    // 删除印章
    const delSealItem = function (id) {
        for (let index = 0; index < posBean[docsCurrentNumber].length; index++) {
            if (posBean[docsCurrentNumber][index]['id'] == id) {
                posBean[docsCurrentNumber].splice(index, 1)
                break
            }
        }
        $("#drag" + id).remove()
    }

    // 解析pdf
    var pdfValue = null;
    var pdfBase64 = null;

    var rendererPdf = function (docsNumber) {
        // 获取文档方式
        const loadType = docsList[docsNumber].loadType;
        // 获取文档值
        const docValue = docsList[docsNumber].docValue;
        // PDF文件

        // if (loadType == "byBase64") {
        //     // 通过文档编号从服务端获取PDF的Base64字符串
        //     // pdfBase64 = getPDFBase64ByAjax();
        //     // 通过Base64获取PDF
        //     // var pdfBase64 = base64Con;
        //     // var pdfFileBinary = convertDataURIToBinary(pdfBase64);
        //     var pdfFileBinary = getPDFBase64ByAjax();
        //     pdfValue = pdfFileBinary;
        // } else {
        //     pdfValue = docValue;
        // }

        // Asynchronous download of PDF
        // 使用方式
        try {
            getPDFBase64ByAjax().then(function (pdf) {
                console.log("PDF loaded, total pages:", pdf.numPages);
                // 可以继续处理 PDF
                for (let index = 1; index <= pdf.numPages; index++) {
                    rendererTemplate(index)
                    renderer(pdf, index)
                }
            }).catch(function (error) {
                console.error("PDF loading failed:", error);
            });
        } catch (error) {
            // console.error("Request failed:", error);
            console.log("Request failed:", error);
        }

        // 解析pdf
        // loadingTask.promise.then(function (pdf) {
        //     console.log('PDF loaded');
        //
        //     console.log(pdf.numPages, '当前文档总页数');
        //     // 遍历 pdf.numPages， 调用 renderer(pdf, n) 获取多文档展示
        //
        //     // Fetch the first page
        //     // const pageNumber = 1;
        //     for (let index = 1; index <= pdf.numPages; index++) {
        //         rendererTemplate(index)
        //         renderer(pdf, index)
        //     }
        //
        // }, function (reason) {
        //     // PDF loading error
        //     console.error(reason);
        // });
    }

    // 切换文档
    var changeDocs = function (event, docsNumber) {
        $(event.target).addClass('current').siblings().removeClass('current')
        $('#signContainer').html('')
        docsCurrentNumber = docsNumber
        rendererPdf(docsNumber)
    }

    //将encodeBase64解码
    convertDataURIToBinary = function (dataURI) {
        var raw = window.atob(dataURI);
        var rawLength = raw.length;
        //转换成pdf.js能直接解析的Uint8Array类型,见pdf.js-4068
        var array = new Uint8Array(new ArrayBuffer(rawLength));
        for (i = 0; i < rawLength; i++) {
            array[i] = raw.charCodeAt(i);
        }
        return array;
    }


    // getPDFBase64ByAjax = function (fileCode) {
    function getPDFBase64ByAjax() {
        var params = new URLSearchParams(window.location.search);
        fdAttId = params.get('fdAttId');
        fdProjectId = params.get('fdProjectId');
        fdFilename = params.get('fdFilename');
        fdUrlHeard = params.get('fdUrlHeard');
        fdLoginName = params.get('fdLoginName');
        fdEntityKey = params.get('fdEntityKey');
        if (null == fdAttId || null == fdProjectId || null == fdFilename) {
            alert("获取数据失败", function () {
                window.close();
                return;
            });
        }
        var xhr = new XMLHttpRequest();
        xhr.open("POST", fdUrlHeard + "openapi/sys-attach/fileStream/download", false); // 同步请求
        xhr.setRequestHeader("Content-type", "application/json");
        // xhr.responseType = 'arraybuffer'; // 关键：直接获取 ArrayBuffer
        xhr.overrideMimeType('text/plain; charset=x-user-defined');
        xhr.send(JSON.stringify({
            "fdId": fdAttId
        }));
        // xhr.send(JSON.stringify({
        //     "fdId": "1ivn88oo3w56ow6p3w33pf7o681mb0g36uw0"
        // }));
        if (xhr.status === 200) {
            var text = xhr.responseText;
            console.log("成功获取到附件")
            var bytes = new Uint8Array(text.length);
            for (var i = 0; i < text.length; i++) {
                bytes[i] = text.charCodeAt(i) & 0xff; // 确保只取低8位
            }
            pdfValue = window.btoa(
                Array.from(bytes, byte => String.fromCharCode(byte)).join('')
            );
            return pdfjsLib.getDocument({data: bytes}).promise; // 返回 PDF 加载的 Promise
        } else {
            throw new Error("Failed to load PDF: HTTP " + xhr.status);
        }

    //     var arrays = [];
    //     await fetch('http://mkdev01.ywork.me/openapi/sys-attach/fileStream/download', {
    //         method: 'POST',
    //         headers: {'Content-Type': 'application/json'},
    //         body: JSON.stringify({
    //             "fdId": "1ivn88oo3w56ow6p3w33pf7o681mb0g36uw0"
    //         })
    //     }).then(res => {
    //         // alert('签章完成!');
    //         console.log('Response:', res); // 即使失败也会触发
    //         const reader = res.body.getReader();
    //         return reader.read();
    //     }).then(result => {
    //         if (result.done) {
    //             console.log('Stream complete');
    //             return;
    //         }
    //         // 将读取的数据转换为Uint8Array
    //         const array = new Uint8Array(result.value);
    //         console.log('Received chunk:', array);
    //         arrays = array;
    //         // 你可以在这里处理接收到的Uint8Array数据块
    //     }).catch(err => {
    //         console.error('Full error:', err);
    //         if (err instanceof TypeError) {
    //             alert("后端服务未启动或网络错误");
    //         }
    //     });
    //     return arrays;
    //
    //     function onClick(evt) {
    //         MKXFORM.callOrg({
    //             id: "sysorg.getCurUserInfo",
    //             param: undefined
    //         }, function (error, res) {
    //             //当前用户
    //             var fdLoginName = res.fdLoginName;
    //             if (MKXFORM.docStatus == '30') {
    //                 var fdFilename = MKXFORM.getValueText('mk_model_20250701gptjc.fd_col_mh4n8w');
    //                 var fdAttId = MKXFORM.getValue('mk_model_20250701gptjc.fd_col_mh4n8w')[0].fdId;
    //                 var fdProjectId = MKXFORM.getFormValues()._dynamicProps.fdId;
    //                 const childWindow = window.open("http://192.168.14.76:9002/mk_api/signature/kmSealdemo/index.home?fdUrlHeard=http://192.168.14.76:9002/" +
    //                     "&fdEntityKey=fd_col_r1oifi&fdAttId=" + fdAttId + "&fdProjectId=" + fdProjectId + "&fdFilename=" + fdFilename + "&fdLoginName=" + fdLoginName);
    //                 // 监听子窗口消息
    //                 window.addEventListener("message", (e) => {
    //                     console.log("收到结果:", e.data);
    //                     if (e.data.type === "RESULTPDF") {
    //                         // 关闭子窗口
    //                         childWindow.close();
    //                         MKXFORM.message.success('签章完成！自动刷新页面！');
    //                         setTimeout(function() {
    //                             //刷新当前页面
    //                             location.reload();
    //                         }, 500);
    //                     }
    //                 });
    //             } else {
    //                 MKXFORM.message.error('权限不足,禁止签章！');
    //             }
    //         });
    //     }
    }

    // 初始化列表+印章
    init()
    // 初始化第一份文档
    rendererPdf(docsCurrentNumber)

    // 确认签署
    const submitSign = function () {
        // 前端显示印章对应的坐标信息
        // mizhu.alert('印章中心点坐标信息JSON字符串', JSON.stringify(posBean));
        const selTrs = posBean[0][0]
        if (null == selTrs) {
            alert("请先选择印章位置!");
            return;
        }
        selTrs.pdfBase64 = pdfValue;
        selTrs.fdProjectId = fdProjectId;
        selTrs.fdAttId = fdAttId;
        selTrs.fdFilename = fdFilename;
        selTrs.fdUrlHeard = fdUrlHeard;
        selTrs.fdEntityKey = fdEntityKey;
        selTrs.fdLoginName = fdLoginName;
        // // 以下为使用Ajax方式将印章对应的坐标信息以JSON形式POST给后端
        fetch('/mk_api/signature/kmSealdemo/getSealBase64', {
            method: 'POST',
            headers: {'Content-Type': 'application/json'},
            body: JSON.stringify(posBean)
        }).then(response => {
            // 检查HTTP状态码
            if (!response.ok) {
                alert("发送签章失败！");
                throw new Error(`HTTP error! status: ${response.status}`);
            }
            return response.json(); // 解析JSON响应
        }).then(data => {
            // 即使失败也会触发
            console.log('返回数据:', data);
            // 处理响应数据
            if (data.status == 101) {
                alert("签章失败！请刷新页面后重试，或联系管理员！");
            } else {
                alert("签章成功！");
                window.opener.postMessage({
                    type: "RESULTPDF",
                    payload: "签章成功"
                }, fdUrlHeard);
            }
        }).catch(error => {
            console.error('请求失败:', error);
            if (error instanceof TypeError) {
                alert("后端服务未启动或网络错误!");
            }
        });
    }

    // 渲染PDF页面
    function renderPage(num) {
        pageRendering = true;
        pdfDoc.getPage(num).then(function (page) {
            const viewport = page.getViewport({scale: scale});
            const canvas = document.getElementById('pdfCanvas');
            const context = canvas.getContext('2d');
            canvas.height = viewport.height;
            canvas.width = viewport.width;

            const renderContext = {
                canvasContext: context,
                viewport: viewport
            };

            const renderTask = page.render(renderContext);
            renderTask.promise.then(function () {
                pageRendering = false;
            });
        });
    }

    // 添加印章
    function addStamp() {
        const stampFile = document.getElementById('stampInput').files[0];
        if (!stampFile || !pdfDoc) return;

        const fileReader = new FileReader();
        fileReader.onload = function (e) {
            const stampImg = new Image();
            stampImg.onload = function () {
                const canvas = document.getElementById('pdfCanvas');
                const ctx = canvas.getContext('2d');

                // 在右下角添加印章
                const x = canvas.width - this.width - 20;
                const y = canvas.height - this.height - 20;

                ctx.drawImage(this, x, y, this.width, this.height);
            };
            stampImg.src = e.target.result;
        };
        fileReader.readAsDataURL(stampFile);
    }


    // 拖拽事件
    // 触发源
    var _ondragstart = function (event, sealData) {
        console.log('start');
        // 或者通过获取 sealId 遍历检索相应的对象获取印章数据
        console.log(event.target.getAttribute('sealId'));

        const pos = {
            'posX': 0, // 签署位置横坐标
            'posY': 0, // 签署位置纵坐标
        };

        const dragData = Object.assign(pos, sealData);

        event.dataTransfer.setData('Text', JSON.stringify(dragData));

        //  IE下没有 setDragImage 这个属性
        if (event.dataTransfer.setDragImage) {
            // 设置鼠标位置
            event.dataTransfer.setDragImage(event.target, 50, 50);
        }
    }

    var _ondragend = function (event) {
        console.log('end');
    }

    // 目标源
    var _ondragenter = function (event) {
        console.log('enter');
    }

    var _ondragover = function (event) {
        event.preventDefault();
        event.stopPropagation();
        console.log('over');
    }

    var _ondragleave = function (event) {
        console.log('leave');
    }

    var _ondrop = function (event, page) {
        event.preventDefault();
        event.stopPropagation();
        console.log('drop');

        const dragData = JSON.parse(event.dataTransfer.getData('Text'));

        const pdf = document.getElementById('signContainer')
        const pageView = document.getElementById('pageView_' + page)

        dragData.posX = event.pageX - pdf.offsetLeft - pageView.offsetLeft
        dragData.posY = pageView.offsetHeight - (event.pageY - (pdf.offsetTop + pageView.offsetTop - pdf.scrollTop))

        // 存储提交印章
        dragData.posPage = page
        dragData.width = dragData.width || 100
        dragData.height = dragData.height || 100;
        dragData.id = 'seal_' + Date.parse(new Date())

        posBean[docsCurrentNumber].push(dragData)
        console.log(dragData, '印章签署相关信息');
        console.log(posBean, 'posBean');

        // 或者直接组装dom，append 插入到 pageView_1
        rendererSealTemplate(dragData, pageView.offsetHeight)
        // const seal_1 = document.getElementById('seal_1')
        // 	  seal_1.style.width = dragData.width + 'px'
        // 	  seal_1.style.height = dragData.height + 'px'
        // 	  seal_1.style.left = dragData.posX - (dragData.width/2) + 'px'
        // 	  seal_1.style.top = pageView.offsetHeight - (dragData.height/2) - dragData.posY + 'px'
        // 	  seal_1.style.backgroundImage = `url(${dragData.sealImg})`
    }
</script>
</body>
</html>